#ifndef _CMP_H
#define _CMP_H

#include "../../engine/address.hpp"
#include "../../utils/libcache/CacheWriteBack.hpp"

#include "constants.h"
#include "tlb.h"

class CMP {
protected:
    TLB *_tlb[32];

    CacheWriteBack <address_t>  *_L0Cache[32];
    uint32_t *_L0CacheHits, *_L0CacheMisses, *_mainMemoryAccesses;

    uint32_t _threads;
    uint32_t _pageSize;
    uint32_t _lineSize;
    uint32_t _L0Size;
    uint32_t _L0Flush;

    virtual void reset();
    void flushL0(uint32_t thread);

public:
    CMP(uint32_t threads, uint32_t pageSize, uint32_t lineSize, uint32_t L0Size);
    virtual ~CMP();
    inline uint32_t getL0CacheHits(int tid)             const { return _L0CacheHits[tid]; }
    inline uint32_t getL0CacheMisses(int tid)           const { return _L0CacheMisses[tid]; }
    inline uint32_t getTlbHits(uint32_t tid)            const { return _tlb[tid]->getTlbHits(); }
    inline uint32_t getTlbMisses(uint32_t tid)          const { return _tlb[tid]->getTlbMisses(); }
    inline uint32_t getMainMemoryAccesses(uint32_t tid) const { return _mainMemoryAccesses[tid];   }
    inline uint32_t getLineSize()                       const { return _lineSize; }
    inline uint32_t getPageSize()                       const { return _pageSize; }
    inline uint32_t getL0Size()                         const { return _L0Size;   }
    inline uint32_t getL0Flush()                        const { return _L0Flush;   }
};

#endif
